/*
 * readline.h
 *
 *  Created on: Jul 28, 2010
 *      Author: Pierre Lindenbaum PhD
 *              plindenbaum@yahoo.fr
 *              http://plindenbaum.blogspot.com
 *              
 */

#ifndef TOKENIZER_H_
#define TOKENIZER_H_


#include <iostream>
#include <vector>
#include <string>

namespace u915 { namespace util {

class CTokenizer
	{
	private:
	    std::vector<char*> tokens;
	    void init(char* p,char delim)
		{
		char* prev=p;
		for(;;)
		    {
		    if(*p==delim || p==0)
			{
			tokens.push_back(prev);
			if(p==0) break;
			*p=0;
			prev=p+1;
			}
		    ++p;
		    }
		}
	public:
		typedef int size_type;
		CTokenizer(char* source,char delim)
		    {
		    init(source,delim);
		    }

		CTokenizer(char* source)
		    {
		    init(source,'\t');
		    }

		virtual ~CTokenizer()
		    {

		    }

		virtual size_type size() const
		    {
		    return tokens.size();
		    }

		virtual const char* at(size_type i) const
		    {
		    assert(i>=0);
		    assert(i<size());
		    return tokens.at((std::vector<char*>::size_type)i);
		    }

		const char* operator[](size_type i) const
		    {
		    return at(i);
		    }
		std::ostream& print(std::ostream& out) const
		    {
		    for(size_type i=0;i< size();++i)
			{
			out << "(" << i << "):" << at(i) << "\n";
			}
		    return out;
		    }

	};

class Tokenizer
	{
	private:
	    std::vector<std::string> tokens;
	    void init(const std::string& s,char delim)
		{
		std::string::size_type i=0;
		std::string::size_type prev=0;
		for(;;)
		    {
		    if(i==s.size() || s[i]==delim)
			{
			tokens.push_back(s.substr(prev,i-prev));
			if(i==s.size()) break;
			prev=i+1;
			}
		    ++i;
		    }
		}
	public:
		typedef int size_type;
		Tokenizer(const std::string s,char delim)
		    {
		    init(s,delim);
		    }

		Tokenizer(const std::string s)
		    {
		    init(s,'\t');
		    }

		virtual ~Tokenizer()
		    {

		    }

		virtual size_type size() const
		    {
		    return tokens.size();
		    }

		virtual const std::string& at(size_type i) const
		    {
		    return tokens.at((std::vector<std::string>::size_type)i);
		    }

		const std::string& operator[](size_type i) const
		    {
		    return at(i);
		    }
		std::ostream& print(std::ostream& out) const
		    {
		    for(size_type i=0;i< size();++i)
			{
			out << "(" << i << "):" << at(i) << "\n";
			}
		    return out;
		    }

	};

std::ostream& operator << (std::ostream& out,const Tokenizer& o)
    {
    return o.print(out);
    }


}}//namespaces

#endif /* TOKENIZER_H_ */
